#include "thread.hpp"
#include <iostream>
#include <thread>
#include <chrono>
#include <vector>
using namespace std;

// 1. 测试普通函数（参数为 string，需传入 std::string 类型）
void print_hello(int count, const string& msg) {
    for (int i = 0; i < count; ++i) {
        cout << "Thread " << ThreadModule::GetThreadNum() - 1 
             << ": " << msg << " (" << i + 1 << "/" << count << ")" << endl;
        this_thread::sleep_for(chrono::milliseconds(100));
    }
}

// 2. 测试优雅退出（参数改为通用的 Thread 基类指针，避免模板类型循环依赖）
// 此处用 void* 接收线程对象指针，内部强制转换（简化模板类型匹配）
void loop_task(void* thread_ptr) {
    // 将 void* 转为 Thread 模板类指针（注意：模板参数需与实际创建的 Thread 一致）
    using ThreadType = ThreadModule::Thread<void(*)(void*), void*>;
    ThreadType* thread = static_cast<ThreadType*>(thread_ptr);

    int count = 0;
    // 等待线程启动
    while (!thread->IsRunning()) {
        this_thread::yield();
    }

    // 通过公共接口 GetStopFlag() 检查停止信号
    while (!thread->GetStopFlag()) {
        cout << "Loop task running... (" << ++count << ")" << endl;
        this_thread::sleep_for(chrono::milliseconds(200));
    }
    cout << "Loop task stopped. Total runs: " << count << endl;
}

// 3. 测试成员函数
class TestClass {
public:
    void member_func(int base) {
        for (int i = 0; i < 3; ++i) {
            cout << "Member function: " << base + i << endl;
            this_thread::sleep_for(chrono::milliseconds(150));
        }
    }
};

int main() {
    cout << "=== Starting thread tests ===" << endl;

    // -------------------------- 测试1：普通函数线程 --------------------------
    // 显式指定模板参数：<函数类型, 参数1类型, 参数2类型>
    ThreadModule::Thread<void(*)(int, const string&), int, string> 
        t1(print_hello, 3, string("Hello from thread 1"));
    cout << "Starting thread 1..." << endl;
    t1.Start();
    t1.Join();
    cout << "Thread 1 test completed\n" << endl;

    // -------------------------- 测试2：优雅退出线程（关键修复） --------------------------
    // 直接初始化，避免默认构造：模板参数为 <函数类型(void(*)(void*)), 参数类型(void*)>
    ThreadModule::Thread<void(*)(void*), void*> 
        t2(loop_task, &t2); // 传入 loop_task 函数 + 当前线程对象指针
    cout << "Starting loop thread..." << endl;
    t2.Start();
    this_thread::sleep_for(chrono::seconds(1)); // 运行1秒后触发停止
    cout << "Sending stop signal to loop thread..." << endl;
    t2.SetStopFlag();
    t2.Join();
    cout << "Loop thread test completed\n" << endl;

    // -------------------------- 测试3：成员函数线程 --------------------------
    TestClass obj;
    // 模板参数：<成员函数类型, 类实例指针类型, 成员函数参数类型>
    ThreadModule::Thread<void(TestClass::*)(int), TestClass*, int> 
        t3(&TestClass::member_func, &obj, 100);
    cout << "Starting member function thread..." << endl;
    t3.Start();
    t3.Join();
    cout << "Member function thread test completed\n" << endl;

    // -------------------------- 测试4：分离线程 --------------------------
    ThreadModule::Thread<void(*)(int, const string&), int, string> 
        t4(print_hello, 5, string("Detached thread message"));
    cout << "Starting detached thread..." << endl;
    t4.Start();
    t4.Detach();
    cout << "Main thread waiting for detached thread to finish..." << endl;
    this_thread::sleep_for(chrono::seconds(1)); // 等待分离线程执行
    cout << "Detached thread test completed\n" << endl;

    // -------------------------- 测试5：多线程并发 --------------------------
    vector<ThreadModule::Thread<void(*)(int, const string&), int, string>*> threads;
    cout << "Starting 3 concurrent threads..." << endl;
    for (int i = 0; i < 3; ++i) {
        auto t = new ThreadModule::Thread<void(*)(int, const string&), int, string>(
            print_hello, 4, string("Concurrent thread ") + to_string(i + 1)
        );
        threads.push_back(t);
        t->Start();
    }
    // 等待所有线程并释放内存
    for (auto t : threads) {
        t->Join();
        delete t;
    }
    cout << "Concurrent threads test completed\n" << endl;

    // -------------------------- 测试6：线程状态查询 --------------------------
    ThreadModule::Thread<void(*)(int, const string&), int, string> 
        t5(print_hello, 2, string("Status test thread"));
    cout << "Thread 5 status before start: " << (t5.IsRunning() ? "running" : "not running") << endl;
    t5.Start();
    cout << "Thread 5 status after start: " << (t5.IsRunning() ? "running" : "not running") << endl;
    cout << "Thread 5 ID: " << t5.GetTid() << endl;
    cout << "Thread 5 name: " << t5.GetName() << endl;
    t5.Join();
    cout << "Thread 5 status after join: " << (t5.IsRunning() ? "running" : "not running") << endl;
    cout << "Status test completed\n" << endl;

    cout << "=== All thread tests completed ===" << endl;
    return 0;
}